<script lang="ts">
	import Divider from '$components/basic/divider/divider.svelte';
	import Product from '$components/business/product/product.svelte';
	import { getValue } from '$utils/get';
	import Button from '@smui/button';
	import IconButton from '@smui/icon-button';
	import Textfield from '@smui/textfield';
	import Action from './action.svelte';
	import { getProductStatus, ITEM_TYPE_ENUM } from '$components/business/product';
	import { onDestroy } from 'svelte';
	import Describe from './describe.svelte';
	import { get, writable } from 'svelte/store';
	import { getCartStore } from '@/store/modules/cart';
	import { createMessage, type MsgOptions } from '$components/basic/message';
	import { Bubble } from '$components/business/bubble';
	import { input_quantity_filter, price_transform } from '$utils/filter';
	import { useUserstore } from '@/store';
	import { usePreOrderStore } from '@/store/modules/pre';
	import { goto } from '$utils/intercept';
	import { debounce } from '$utils/debounce';

	const colorList = {
		primary: '#3b82f6',
		success: '#10b981',
		danger: '#ef4444',
		warning: '#eab308',
		info: '#6b7280',
		light: '#f3f4f6',
		close: '#d1d5db'
	};

	export let orderInfo: Partial<Product.Detail> = {};
	export let style: string = '';

	let showAll = false;
	let num = 800;
	let productStatus = writable({
		offsetTime: 0,
		HasTimer: false,
		ColorType: 'primary',
		CanPlaceOrder: false,
		TipIndex: 0,
		displayText: ''
	});
	let circleComputed: NodeJS.Timeout;
	let cartStore = getCartStore();
	let buttonStyle = '--mdc-theme-primary: #d1d5db; cursor: not-allowed';
	const getButtonStyle = () => {
		const couldNotClickStyle = '--mdc-theme-primary: #d1d5db; cursor: not-allowed';
		const commonClickStyle = `--mdc-theme-primary: ${colorList[$productStatus.ColorType]}`;

		if (orderInfo.itemType === ITEM_TYPE_ENUM.CLOSE_OUT) {
			if ($productStatus.offsetTime > 0) return commonClickStyle;
		} else if ($productStatus.CanPlaceOrder) return commonClickStyle;

		return couldNotClickStyle;
	};
	const overStock = () => orderInfo.stock! - orderInfo.ordernums! <= 0;
	const computedStatus = debounce(() => {
		circleComputed = setInterval(() => {
			const result = getProductStatus(orderInfo as Product.Detail, new Date());
			if (overStock()) {
				if (circleComputed) clearInterval(circleComputed);
				Object.assign(result, { ColorType: 'close', CanPlaceOrder: false });
			}
			productStatus.update((value) => Object.assign(value, result));
			const styleText = getButtonStyle();
			if (buttonStyle !== styleText) buttonStyle = styleText;
		}, 200);
	}, 300);

	const add_cart = async (orderInfo: Partial<Product.Detail>, slient = false) => {
		const result = await cartStore.addCartItem(orderInfo as Product.Detail);
		const messageOptions = result
			? { type: 'success', message: 'Success added to cart', duration: 2000 }
			: { type: 'warning', message: 'already exists', duration: 2000 };

		if (!slient) return createMessage(messageOptions as MsgOptions);
		return result;
	};

	const add_order = async (orderInfo: Partial<Product.Detail>) => {
		if (!$productStatus.CanPlaceOrder)
			return createMessage({ type: 'warning', message: 'Cannot place order' });
		if (get(useUserstore().token) === '') {
			return createMessage({ type: 'danger', message: 'Please log in before placing an order' });
		}
		await add_cart(orderInfo, true);

		if (orderInfo.id) {
			usePreOrderStore().setPreOrders([String(orderInfo.id)]);
			return goto('/order/confirm');
		}
	};

	$: info_double = [
		{ name: 'Type: ', icon: 'package_2', value: orderInfo.itemType, style: 'color: #3b82f6' },
		{ name: 'Series: ', icon: 'content_copy', value: orderInfo.series },
		{ name: 'Code: ', icon: 'barcode', value: orderInfo.code },
		{ name: 'Dash: ', icon: 'sensors', value: orderInfo.dash },
		{ name: 'Vision: ', icon: 'attach_file', value: orderInfo.country },
		{ name: 'Casepack: ', icon: 'wifi_tethering', value: orderInfo.casepack }
	];

	$: info_single = [
		{ name: 'Delivery ETA: ', icon: 'calendar_month', value: orderInfo.ship_at },
		{ name: 'MOQ: ', icon: 'shift', value: `${orderInfo.moq || ''} PCS` },
		{
			name: 'Unit Price: ',
			icon: 'payments',
			value: (() => {
				if (String(orderInfo.price).length >= 8) return '<b>login to see price</b>';
				const price = (Number(orderInfo.price) * orderInfo.discount!).toFixed(2);
				if (orderInfo.discount && orderInfo.discount !== 1)
					return `<del>$ ${orderInfo.price}</del> <span style="color: #ef4444; font-size: 18px; font-weight: 600">$ ${price}</span>`;
				return price;
			})(),
			handle: true
		}
	];

	$: total = price_transform(Number(orderInfo.price!) * Number(orderInfo.num));
	$: discount = orderInfo.discount || 1;

	$: if (orderInfo.id) {
		computedStatus();
	}

	onDestroy(() => {
		clearInterval(circleComputed);
	});

	/**
	 * 下面主要处理数量
	 */
	const getMax = () => {
		const max_default = Number(orderInfo.max);
		const maxValue = Number(
			max_default && !isNaN(max_default) ? orderInfo.max : orderInfo.remainder_stock
		);
		const stock = Number(orderInfo.remainder_stock);
		return Math.min(maxValue, stock);
	};
	const getMin = () => Number(orderInfo.moq!);
	const add = () => reset_amount(Number(orderInfo.num) + Number(orderInfo.moq!));
	const minus = () => reset_amount(Number(orderInfo.num) - Number(orderInfo.moq!));
	const valid_quantity = (value: number, info: Partial<Product.Detail>): [boolean, number] => {
		if (isNaN(value)) return [false, info.moq!];

		const moq = Number(info.moq!);
		const max = getMax();

		if (value && value % moq === 0 && value >= info.moq! && ((max && value <= max!) || !max)) {
			return [true, value];
		} else {
			return [false, value];
		}
	};
	let showTotal = false;
	const reset_amount = (v: number) => {
		showTotal = true;
		const moq = Number(orderInfo.moq!);
		const [status, value] = valid_quantity(v, orderInfo);
		if (status) orderInfo.num = value;
		else {
			const multiple = Math.floor(value / moq);
			orderInfo.num = input_quantity_filter(multiple * moq, getMax(), getMin());
		}
	};
	const changeQuantity = () => reset_amount(Number(orderInfo.num));

	const fmt = (...args: any[]) => {
		if (args.some((i) => i === 'login to see price')) return 'login to see price';
		const discount = orderInfo.discount || 1;
		return price_transform(args.reduce((a, b) => Number(a) * Number(b), discount));
	};
</script>

<div class="flex-1 flex flex-col justify-start pl-20px" {style}>
	<div class="title font-size-28px line-height-48px font-500 cursor-pointer">{orderInfo.title}</div>
	<div class="w-full flex flex-row items-center bg-gray-1 px-1 py-3">
		<Describe {info_double} {info_single}></Describe>
	</div>
	<!-- <div class="w-full p-40px bg-green-6 rounded-md mt-5px"></div> -->
	{#if $productStatus.HasTimer}
		<Action
			offsetTime={$productStatus.offsetTime}
			color={colorList[$productStatus.ColorType]}
			info={$productStatus.displayText}
		></Action>
	{/if}

	{#if $productStatus.HasTimer && orderInfo.itemType === ITEM_TYPE_ENUM.CLOSE_OUT}
		<div
			class="progress-container w-full h-fit relative mt-10px"
			style={`--mdc-theme-primary: ${colorList[$productStatus.ColorType]};`}
		>
			<div
				class="progress-dot color-gray-1 rounded font-bold font-size-16px flex-cc"
				style={`left: ${Math.ceil((Number(orderInfo.ordernums) / Number(orderInfo.stock)) * 100 + 2)}%`}
			>
				{Math.ceil((Number(orderInfo.ordernums) / Number(orderInfo.stock)) * 100)}%
			</div>
			<progress class="w-full" value={orderInfo.ordernums} max={orderInfo.stock}></progress>
		</div>
	{/if}

	<Bubble class="w-full flex-cc gap-10px mb-2">
		<span class="font-size-18px">Quantity: </span>
		<IconButton class="material-symbols-outlined" on:click={minus}>remove</IconButton>
		<Textfield
			class="reset-input-text-align flex-1 text-input-center"
			on:blur={changeQuantity}
			bind:value={orderInfo.num}
		></Textfield>
		<IconButton class="material-symbols-outlined" on:click={add}>add</IconButton>
	</Bubble>

	<Button
		variant="raised"
		class="h-80px min-h-60px gap-20px"
		style={buttonStyle}
		on:click={() => {
			if (orderInfo.itemType === ITEM_TYPE_ENUM.CLOSE_OUT) {
				if ($productStatus.offsetTime > 0) return add_order(orderInfo);
				else {
					const errMsg = 'The pre-order has ended';
					return createMessage({ message: errMsg, type: 'warning' });
				}
			} else if ($productStatus.CanPlaceOrder) return add_cart({ num, ...orderInfo });
		}}
	>
		<span class="material-symbols-outlined">
			{orderInfo.itemType === ITEM_TYPE_ENUM.CLOSE_OUT ? 'shopping_bag' : 'add_shopping_cart'}
		</span>
		{#if $productStatus.CanPlaceOrder}
			<span>{orderInfo.itemType === ITEM_TYPE_ENUM.CLOSE_OUT ? 'Ordering now' : 'add to cart'}</span
			>
			{#if showTotal}
				<span>
					<span class="font-size-18px">USD</span>
					<span class="font-bold font-size-18px">
						{fmt(orderInfo.price, orderInfo.num)}
					</span>
				</span>
			{/if}
		{:else}
			<span>Out of stock</span>
		{/if}
	</Button>
</div>

<style>
	progress {
		position: relative;
		background-color: #d1d5db;
		border-radius: 999px;
	}

	progress::-webkit-progress-bar {
		background-color: #d1d5db;
		border-radius: 999px;
	}

	progress::-webkit-progress-value {
		background: repeating-linear-gradient(
				135deg,
				var(--mdc-theme-primary) 0 10px,
				color-mix(in lch, var(--mdc-theme-primary) 70%, #fff 30%) 0 20px
			)
			0/100%;
		border-radius: 999px;
	}

	progress::-moz-progress-bar {
		background-color: var(--mdc-theme-primary);
		border-radius: 999px;
	}

	/* 添加一个点来模拟进度条上的点 */
	.progress-dot {
		z-index: 3;
		display: flex;
		position: absolute;
		width: 46px;
		height: 30px;
		top: 50%;
		left: 0; /* 位于进度条的中间 */
		transform: translate(-50%, -50%);
		background-color: color-mix(in lch, var(--mdc-theme-primary) 98%, #000 2%); /* 点的颜色 */
		user-select: none; /* 防止点被选中 */
	}
</style>
